{$R-}                             {Range checking off}
{$B+}                             {Boolean short circuiting off}
{$S-}                             {Stack checking off}
{$I-}                             {I/O checking off}
{$N-}                             {No numeric coprocessor}
{$V-}                             { disable string parameter type checking - faster }
{$M 65500,16384,655360}           {Turbo 3 default stack and heap}

{******************************************************}
{           The Adventure Game Toolkit (tm)            }
{ Copyright 1994 by Mark J. Welch and David R. Malmberg}
{                 All Rights Reserved                  }
{                                                      }
{              Version 1.7 (May 20, 1994)              }
{******************************************************}
(*
AGT is now "freeware."  This means that the authors, David Malmberg and Mark
Welch, still retain the copyright to AGT and all of its related files, such
as the documentations and sample games.  However, you or any other user may
use the AGT system to develop and distribute your own games without paying any
royalty to the AGT authors.
*)

{$DEFINE NormalVersion}           (* Normal version -- NOT BIG version *)

PROGRAM Run;

USES
  Crt,
  Dos,
  Graph3,
  Turbo3,
  RUNPART1,
  RUNPART2,
  RUNPART3;

  {************************}
  {     Main Program       }
  {************************}

CONST
  TopLine = '                                                  SCORE:         MOVE:          ';

VAR Xpos, Ypos : Integer;         {X,Y place within small window}
  Current_Score, Original_Cursor, ThenSpot, AndSpot,
  FirstSpot, xxx, yyy, i, J : Integer;
  Vany, Nany, Oany : words;
  PreviousInput, ItsLocation : s;

BEGIN                             {Main Program}
  Randomize;
 (*
  Assign(Input,''); Reset(Input); {allow I/O redirection, i.e., thru COM ports}
  Assign(Output,''); Rewrite(Output);
 *)
  AssignLst(IO, 0);               {set up Scripting to LPT 1 as TP 4.0 Text File}
  Rewrite(IO);
  Scripting := False;
  CheckBreak := False;            {Turn off Control Breaking}
  CheckParams;                    { in PARAM.PA4 }
  ChangeCursor(8192, Original_Cursor); {make cursor invisible, but save shape}
  ChangeCursor(8192, Original_Cursor); {make cursor invisible, but save shape}
  ResurrectedFlag := True;
  Previous_room := 1000;
  PreviousInput := ' ';
  Title;                          { in TITLE.PA4 }
  Init_verbs;                     { in INIT.PA4 }
  ScoreAdjustment := 0;
  Set_Token_Parameters;
  ReadFinalVersion;
  IF Intro_Ptr.start >= 1 THEN Pause;
  CLRSCR;
  Read_INSTRUCTIONS;              { If INS file exists }
  morecount := 0;
  Skip_A_Line := True;            {between input and response}
  WriteLn(IO, ' ');
  WriteLn(IO, ' ');
  Describe_scene;                 { in DESCRIBE.PA4 }
  REPEAT
    Xpos := WHEREX;
    Ypos := WHEREY;
    BigWindow;
    Current_Score := ScoreValue;
    GOTOXY(1, 1);                 {Home}
    reverse; WriteLn(TopLine);
    GOTOXY(2, 1); Write(Room[Current_room]^.name);
    GOTOXY(58, 1); Write(Current_Score);
    GOTOXY(72, 1); Write(Num_turns);
    LittleWindow;
    GOTOXY(Xpos, Ypos);
    normal;
    WriteLn(IO, ' ');
    Write(IO, 'What Now? ');
    highlight;
    ChangeCursor(13, Old_Cursor); {make cursor visible}
    LastVerb := ' ';
    OK_To_Display_Keys := True;
    LastPart := GetInputString;
    OK_To_Display_Keys := False;
    Handle_Word_Combinations(LastPart);
    CheckForName(LastPart);
    {Checks to see if the command is being addressed to a creature}
    {If it is then routine sets Global NameStr to name of creature and}
    {  the Global NameNum to the creature's number.}
    {If it is NOT then routine sets Global NameStr to '' and}
    {  the Global NameNum to 0.}
    {After returning from this routine, sentence has the name (if any) stripped off}
    PreviousCompoundCommands := False;
    DoingCompoundCommands := False;
    ChangeCursor(8192, Old_Cursor); {make cursor invisible}
    normal;
    morecount := 0;
    IF POS('COLORS', LastPart) = 1
    THEN BEGIN
      SetColors(LastPart);
      BigWindow;
      normal;
      CLRSCR;
      GOTOXY(1, 1);               {Home}
      reverse; WriteLn(TopLine);
      GOTOXY(2, 1); Write(Room[Current_room]^.name);
      GOTOXY(58, 1); Write(Current_Score);
      GOTOXY(72, 1); Write(Num_turns);
      LittleWindow;
      normal;
      CLRSCR;
      WriteLn(IO, ' ');
      verb := 'LOOK';
      Describe_scene;             { in DESCRIBE.PA4 }
    END
    ELSE IF LastPart = 'DEBUGCOMMANDS'
    (* Debugging feature -- Toggle the "Debugging" Flag *)
    THEN BEGIN
      WriteLn(IO, ' ');
      Flag[0] := NOT Flag[0];     (* Toggle it *)
      verb := 'LOOK';
      Describe_scene;             { in DESCRIBE.PA4 }
    END
    ELSE IF LastPart = 'GETNOUN'
    (* Debugging feature -- move a NOUN to player *)
    THEN BEGIN
      WriteLn(IO, ' ');
      WriteLn(IO, 'What NOUN would you like to get?');
      Write(IO, 'Enter the NOUN number (', First_noun, ' to ', MaxNoun, '): ');
      ReadLn(xxx);
      WriteLn(IO, ' ');
      MoveIt(xxx, Player);
      WriteLn(IO, ' ');
      verb := 'LOOK';
      Describe_scene;             { in DESCRIBE.PA4 }
    END
    ELSE IF LastPart = 'MOVENOUN'
    (* Debugging feature -- move a NOUN to another room *)
    THEN BEGIN
      WriteLn(IO, ' ');
      WriteLn(IO, 'What NOUN would you like to move?');
      Write(IO, 'Enter the NOUN number (', First_noun, ' to ', MaxNoun, '): ');
      ReadLn(xxx);
      WriteLn(IO, ' ');
      WriteLn(IO, 'What ROOM would you like to move the NOUN to?');
      Write(IO, 'Enter the ROOM number (', First_Room, ' to ', MaxRoom, '): ');
      ReadLn(yyy);
      MoveIt(xxx, yyy);
      WriteLn(IO, ' ');
      verb := 'LOOK';
      Describe_scene;             { in DESCRIBE.PA4 }
    END
    ELSE IF LastPart = 'MOVECREATURE'
    (* Debugging feature -- move a CREATURE to another room *)
    THEN BEGIN
      WriteLn(IO, ' ');
      WriteLn(IO, 'What CREATURE would you like to move?');
      Write(IO, 'Enter the CREATURE number (', First_creature, ' to ', MaxCreature, '): ');
      ReadLn(xxx);
      WriteLn(IO, ' ');
      WriteLn(IO, 'What ROOM would you like to move the CREATURE to?');
      Write(IO, 'Enter the ROOM number (', First_Room, ' to ', MaxRoom, '): ');
      ReadLn(yyy);
      MoveIt(xxx, yyy);
      WriteLn(IO, ' ');
      verb := 'LOOK';
      Describe_scene;             { in DESCRIBE.PA4 }
    END
    ELSE IF LastPart = 'MOVEPLAYER'
    (* Debugging feature -- move player to another room *)
    THEN BEGIN
      WriteLn(IO, ' ');
      WriteLn(IO, 'What ROOM would you like to move the PLAYER to?');
      Write(IO, 'Enter the ROOM number (', First_Room, ' to ', MaxRoom, '): ');
      ReadLn(Current_room);
      WriteLn(IO, ' ');
      verb := 'LOOK';
      Describe_scene;             { in DESCRIBE.PA4 }
    END
    ELSE IF LastPart = 'LISTROOMS'
    (* Debugging feature -- List all the ROOM numbers and descriptions *)
    THEN BEGIN
      WriteLn(IO, ' ');
      FOR i := First_Room TO MaxRoom DO
        WriteLn(IO, ' ', i, '   ', Room[i]^.name);
      WriteLn(IO, ' ');
      verb := 'LOOK';
      Describe_scene;             { in DESCRIBE.PA4 }
    END
    ELSE IF LastPart = 'LISTNOUNS'
    (* Debugging feature -- List all the NOUN numbers, descriptions and locations *)
    THEN BEGIN
      WriteLn(IO, ' ');
      FOR i := First_noun TO MaxNoun DO
        BEGIN
          J := N[i]^.location;
          IF J = Player THEN ItsLocation := 'Player carrying it'
          ELSE IF J = Wearing THEN ItsLocation := 'Player wearing it'
          ELSE IF J = 0 THEN ItsLocation := 'NoWhere'
          ELSE IF (J >= First_Room) AND (J <= MaxRoom)
          THEN ItsLocation := Room[J]^.name
          ELSE IF (J >= First_noun) AND (J <= MaxNoun)
          THEN ItsLocation := N[J]^.adj+' '+N[J]^.name
          ELSE IF (J >= First_creature) AND (J <= MaxCreature)
          THEN ItsLocation := M[J]^.adj+' '+M[J]^.name
          ELSE ItsLocation := 'Undefined!';
          WriteLn(IO, ' ', i, '   ', N[i]^.adj, ' ', N[i]^.name, '  -- Located at ', J, '  ', ItsLocation);
        END;
      WriteLn(IO, ' ');
      verb := 'LOOK';
      Describe_scene;             { in DESCRIBE.PA4 }
    END
    ELSE IF LastPart = 'LISTCREATURES'
    (* Debugging feature -- List all the CREATURE numbers, descriptions and locations *)
    THEN BEGIN
      WriteLn(IO, ' ');
      FOR i := First_creature TO MaxCreature DO
        BEGIN
          J := M[i]^.location;
          IF J = Player THEN ItsLocation := 'Player carrying it'
          ELSE IF J = Wearing THEN ItsLocation := 'Player wearing it'
          ELSE IF J = 0 THEN ItsLocation := 'NoWhere'
          ELSE IF (J >= First_Room) AND (J <= MaxRoom)
          THEN ItsLocation := Room[J]^.name
          ELSE IF (J >= First_noun) AND (J <= MaxNoun)
          THEN ItsLocation := N[J]^.adj+' '+N[J]^.name
          ELSE IF (J >= First_creature) AND (J <= MaxCreature)
          THEN ItsLocation := M[J]^.adj+' '+M[J]^.name
          ELSE ItsLocation := 'Undefined!';
          WriteLn(IO, ' ', i, '   ', M[i]^.adj, ' ', M[i]^.name, '  -- Located at ', J, '  ', ItsLocation);
        END;
      WriteLn(IO, ' ');
      verb := 'LOOK';
      Describe_scene;             { in DESCRIBE.PA4 }
    END
    ELSE IF LastPart = 'PRINT ORDER FORM'
    THEN BEGIN
      Print_Order_Form;
      CLRSCR;
      WriteLn(IO, ' ');
      WriteLn(IO, 'You just received 10 extra points for printing the order form.');
      ScoreAdjustment := ScoreAdjustment+10;
      WriteLn(IO, ' ');
      verb := 'LOOK';
      Describe_scene;             { in DESCRIBE.PA4 }
    END
    ELSE REPEAT                   {******** Main Command Loop *********}
      IF (LastPart = 'AGAIN') OR (LastPart = 'G') {repeat previous input}
      THEN LastPart := PreviousInput
      ELSE PreviousInput := LastPart; {Needed for AGAIN or G command}
      ThenSpot := POS(' THEN ', LastPart);
      AndSpot := POS(' AND ', LastPart);
      IF (ThenSpot+AndSpot = 0)
      THEN BEGIN                  {no 'AND' or 'THEN' in command}
        sentence := LastPart;
        DoingCompoundCommands := False;
      END
      ELSE BEGIN                  {'AND' or 'THEN' in command - so let's do first part of command}
        DoingCompoundCommands := True;
        PreviousCompoundCommands := True;
        IF ThenSpot < AndSpot
        THEN FirstSpot := ThenSpot
        ELSE FirstSpot := AndSpot;
        IF ThenSpot = 0 THEN FirstSpot := AndSpot;
        IF AndSpot = 0 THEN FirstSpot := ThenSpot;
        sentence := Copy(LastPart, 1, FirstSpot-1);
        LastPart := Copy(LastPart, FirstSpot+5, 255); {after 'AND' or 'THEN'}
      END;
      DoNormalCMD := True;
      Parse(sentence, verb, noun, prep, object_word, syntax_error); { in PARSE.PA4 }
      LastVerb := verb;
      IF NOT syntax_error THEN
        BEGIN
          Num_turns := Num_turns+1;
          IF ResurrectedFlag
          THEN NewLifeFlag := True
          ELSE NewLifeFlag := False;
          ResurrectedFlag := False;
          IF Any_Special_Cmds THEN
            BEGIN
              Vany := 'ANY';
              Nany := 'ANY';
              Oany := 'ANY';
              TempNameNum := NameNum; {save name number}
              NameNum := 0;       {Number for NO Addressee -- i.e., "TRUE" ANY CMDs}
              PERFORM_Special_CMDS(Vany, Nany, Oany); {automatic "ANY" CMDs}
              NameNum := TempNameNum; {Restore Correct Addressee number}
              IF ((NameNum <> 0) AND (NameNum <> Num_Verbs+1)) THEN
                {This Command has been addressed to someone}
                {Try Commands addressed to ANYONE or ANYBODY First}
                BEGIN
                  TempNameNum := NameNum; {save name number}
                  NameNum := Num_Verbs+1; {Number for ANYBODY}
                  PERFORM_Special_CMDS(verb, noun, object_word);
                  NameNum := TempNameNum; {Restore Correct Addressee number}
                END;
              IF DoNormalCMD THEN PERFORM_Special_CMDS(verb, noun, object_word);
              {specific Verb Noun Object CMDs}
            END;                  {special CMDs}
          IF DoNormalCMD THEN Check_If_Here(noun, object_word); {in ANIMATE}
          { check if noun and object are here}
          IF DoNormalCMD THEN Execute_cmd(verb, noun, prep, object_word); { in EXECUTE.PA4 }
          Describe_scene;         { in DESCRIBE.PA4 }
          Animate; { creatures }  { in ANIMATE.PA4 }
          game_won := Room[Current_room]^.game_win;
          game_end := Room[Current_room]^.game_end;
          IF NOT player_dead THEN player_dead := Room[Current_room]^.player_dead;
        END;
      IF (player_dead) AND (NOT game_end) AND (Max_Lives > 0) THEN Resurrect;
      {if current_life <= Max_Lives}
      morecount := morecount+2;
    UNTIL (verb = 'QUIT') OR (verb = 'Q') OR (player_dead) OR (game_won) OR (game_end)
    OR (syntax_error) OR (NOT DoingCompoundCommands);

  UNTIL (verb = 'QUIT') OR (verb = 'Q') OR (player_dead) OR (game_won) OR (game_end);
  show_score;                     { in EXECSUBS.PA4 }
  Close(descr_file);
  RestoreCursor;                  {restore "standard" cursor}

END.
